#include "Channel.h"
#include <sys/epoll.h>
#include <assert.h>

#include "Logger.h"
#include "EventLoop.h"

const int Channel::KNoneEvent = 0;
const int Channel::KReadEvent = EPOLLIN | EPOLLPRI;
const int Channel::KWriteEvent = EPOLLOUT;


Channel::Channel(EventLoop *loop, int fd)
    :loop_(loop),
    fd_(fd),
    events_(0),
    revents_(0),
    index_(-1),
    tied_(false),
    eventHandling(false)
{
}

Channel::~Channel()
{
    assert(!eventHandling);
}

// fd得到poller通知之后，处理事件
void Channel::handleEvent(Timestamp receiveTime)
{
    std::shared_ptr<void> guard;
    if(tied_) 
    {
        // 将弱指针提升为强指针，判断是否存活，如果存活继续处理
        guard = tie_.lock();
        if(guard) 
        {
            handlerEventWithGuard(receiveTime);
        }
    }  
    else 
    {
        handlerEventWithGuard(receiveTime);
    }
}

void Channel::tie(const std::shared_ptr<void> & obj)
{
    tie_ = obj;
    tied_ = true; 
}

void Channel::remove()
{
    loop_->removeChannel(this);
}

// 改变chnnel所表示的fd的events事件后，update负载在poller中更改fd相对应的事件
void Channel::update()
{
    // 通过channel所属的eventloop去调用poller的相应方法，去注册fd的events
    loop_->updateChannel(this);
}

// 根据poller监听的channle发送的具体事件，由channel负责调用具体的回调函数
void Channel::handlerEventWithGuard(Timestamp receiveTime)
{
    LOG_INFO("channel handleEvent revents:%d",revents_);
    eventHandling = true;
    if ((revents_ & EPOLLHUP) && !(revents_ & EPOLLIN))
    {
        if (closeCallback_)
        {
            closeCallback_();
        }
    }
    if (revents_ & EPOLLERR)
    {
        if (errorCallback_)
        {
            errorCallback_();
        }
    }

    if (revents_ & EPOLLIN)
    {
        if (readCallback_)
        {
            readCallback_(receiveTime);
        }
    }

    if (revents_ & EPOLLOUT)
    {
        if (writeCallback_)
        {
            writeCallback_();
        }
    }
    eventHandling = false;
}
